<template>
	<div class="login-container">
		<div class="login-card">
			<div class="logo-container">
				<div class="logo">
					<img class="w-full" src="@/assets/images/logo.png" />
				</div>
			</div>

			<h2 class="login-title">BillionMail</h2>

			<n-form ref="formRef" size="large" :model="form" :rules="rules">
				<n-form-item :show-label="false" path="username">
					<n-input v-model:value="form.username" :placeholder="t('login.form.usernamePlaceholder')">
					</n-input>
				</n-form-item>
				<n-form-item :show-label="false" path="password">
					<n-input
						v-model:value="form.password"
						class="password-input"
						type="password"
						show-password-on="click"
						:placeholder="t('login.form.passwordPlaceholder')"
						@keyup.enter="handleLogin">
					</n-input>
				</n-form-item>
				<n-form-item v-if="isCode" :show-label="false" path="validate_code">
					<n-input
						v-model:value="form.validate_code"
						class="flex-1"
						:placeholder="t('login.form.captcha')"
						:input-props="{ spellcheck: false }"
						@keydown.enter="handleLogin">
					</n-input>
					<n-spin size="small" :show="codeLoading">
						<div class="code" @click="getCode()">
							<img
								class="w-full h-full"
								:src="codeUrl"
								:title="t('login.form.changeCaptcha')"
								:alt="t('login.form.captcha')" />
						</div>
					</n-spin>
				</n-form-item>
				<n-form-item :show-label="false" :show-feedback="false">
					<n-button
						type="primary"
						size="large"
						class="font-bold"
						:loading="loading"
						:disabled="loading"
						:block="true"
						@click="handleLogin">
						{{ t('login.form.loginButton') }}
					</n-button>
				</n-form-item>
			</n-form>
		</div>
	</div>
</template>

<script lang="ts" setup>
import { useUserStore } from '@/store'
import { isObject } from '@/utils'
import { getValidateCode, login } from '@/api/modules/user'

const { t } = useI18n()

const router = useRouter()
const userStore = useUserStore()

const formRef = useTemplateRef('formRef')

const isCode = ref(false)

const codeUrl = ref('')

const codeLoading = ref(false)

const form = reactive({
	username: '',
	password: '',
	validate_code: '',
	validate_code_id: '',
})

const rules = {
	username: {
		required: true,
		message: t('login.validation.usernameRequired'),
		trigger: ['blur', 'input'],
	},
	password: {
		required: true,
		message: t('login.validation.passwordRequired'),
		trigger: ['blur', 'input'],
	},
	validate_code: {
		required: true,
		trigger: ['blur', 'input'],
		message: t('login.validation.captchaRequired'),
	},
}

interface CodeResponse {
	mustValidateCode: boolean
	validateCodeBase64: string
	validateCodeId: string
}

const getCode = async () => {
	try {
		codeLoading.value = true
		const res = await getValidateCode()
		if (isObject<CodeResponse>(res)) {
			isCode.value = res.mustValidateCode
			if (res.mustValidateCode) {
				codeUrl.value = res.validateCodeBase64
				form.validate_code_id = res.validateCodeId
			}
		}
	} finally {
		codeLoading.value = false
	}
}

const loading = ref(false)

interface LoginResponse {
	token: string
	refresh_token: string
	ttl: number
}

const handleLogin = async () => {
	try {
		await formRef.value?.validate()
		loading.value = true
		const res = await login(toRaw(form))
		if (isObject<LoginResponse>(res)) {
			userStore.setLoginInfo({
				token: res.token,
				refresh_token: res.refresh_token,
				ttl: res.ttl,
			})
			setTimeout(() => {
				router.push('/')
			}, 1000)
		}
	} catch {
		getCode()
	} finally {
		loading.value = false
	}
}

getCode()
</script>

<style lang="scss" scoped>
.login-container {
	--text-dark: var(--color-text-1);
	--text-light: var(--color-text-2);
	--accent-green: #25cdb1;
	--accent-purple: #7e6ed5;
	--border-light: #ddd;
}

.login-container {
	display: flex;
	position: relative;
	justify-content: center;
	align-items: center;
	min-height: 100%;
	background: var(--color-bg-3);
	overflow: hidden;
	&::before {
		content: '';
		position: absolute;
		top: -15%;
		right: -15%;
		width: 40vw;
		height: 40vw;
		border-radius: 50%;
		background-color: var(--accent-green);
		z-index: 0;
	}
	&::after {
		content: '';
		position: absolute;
		left: -15%;
		bottom: -15%;
		width: 40vw;
		height: 40vw;
		border-radius: 50%;
		background-color: var(--accent-purple);
		z-index: 0;
	}
}

.login-card {
	width: 100%;
	max-width: 400px;
	background-color: var(--color-bg-1);
	padding: 52px 32px 62px;
	border-radius: 8px;
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
	z-index: 1;
}

.logo {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 70px;

	&-container {
		display: flex;
		align-items: center;
		justify-content: center;
	}

	&-icon {
		width: 24px;
		height: 24px;
		color: white;
	}

	&-text {
		font-size: 20px;
		font-weight: 600;
		color: var(--text-dark);
	}
}

.login-title {
	margin-top: 0;
	margin-bottom: 32px;
	text-align: center;
	font-weight: 500;
	color: var(--text-dark);
}

.code {
	width: 120px;
	height: 40px;
	margin-left: 12px;
	border-radius: 4px;
	border: 1px solid #dcdfe6;
	overflow: hidden;
	cursor: pointer;
}
</style>
